import datetime

from coin.exchange.base.kr_rest.derivative_util import (PERPETUAL_DATE)
import coin.exchange.ftx_futures.kr_rest.exp_util as exp_util
from coin.exchange.ftx_futures.kr_rest.constants import contract_type_list
from coin.exchange.huobi_futures.kr_rest.constants import quarter_contract_date


def to_native_expiry_str(expiry, contract_type):
  if contract_type == 'perpetual':
    assert expiry == PERPETUAL_DATE
    return 'PERP'
  elif contract_type in contract_type_list:
    return expiry.strftime('%m%d')
  else:
    raise ValueError(contract_type)


def to_expiry_contract_type(expiry_str, current_datetime):
  if expiry_str.isdigit():
    expiry = datetime.datetime.strptime(expiry_str, '%Y%m%d')
    contract_type = find_contract_type_from_expiry(
        current_datetime, datetime.datetime.strptime(expiry_str, '%Y%m%d'))
  elif expiry_str == 'perpetual':
    expiry = PERPETUAL_DATE
    contract_type = 'perpetual'
  elif expiry_str in contract_type_list:
    contract_type = expiry_str
    expiry = find_expiry_from_contract_type(current_datetime, contract_type)
  else:
    raise ValueError(expiry_str, current_datetime)
  return expiry, contract_type


def find_contract_type_from_expiry(current_datetime, expiry):
  if expiry == PERPETUAL_DATE:
    return 'perpetual'
  expiry = exp_util.expiry_accurate_datetime(expiry)
  assert expiry.date().strftime('%Y%m%d') in quarter_contract_date, expiry
  time_delta = expiry - current_datetime
  if time_delta < datetime.timedelta():
    return 'expired'
  elif expiry == find_expiry_from_contract_type(current_datetime, 'quarter'):
    return 'quarter'
  elif expiry == find_expiry_from_contract_type(current_datetime, 'next_quarter'):
    return 'next_quarter'
  else:
    raise ValueError(current_datetime, expiry)


def find_expiry_from_contract_type(current_datetime, contract_type):
  assert contract_type in contract_type_list, contract_type
  if contract_type == 'perpetual':
    return PERPETUAL_DATE
  if contract_type == 'quarter':
    return exp_util.find_quarter_contract_expiring_date(quarter_contract_date, current_datetime)
  elif contract_type == 'next_quarter':
    return exp_util.find_next_quarter_contract_expiring_date(quarter_contract_date, current_datetime)
  else:
    raise ValueError(current_datetime, contract_type)


def parse_native_expiry_contract_type(expiry_str, current_datetime):
  if expiry_str in ['PERP', 'PERPETUAL']:
    expiry = PERPETUAL_DATE
    contract_type = 'perpetual'
  elif expiry_str.isdigit():
    assert len(expiry_str) == 4, expiry_str
    year = current_datetime.year
    if expiry_str < current_datetime.strftime('%m%d'):
      year = year + 1
    expiry_str = str(year) + expiry_str
    expiry = datetime.datetime.strptime(expiry_str, '%Y%m%d')
    expiry = exp_util.expiry_accurate_datetime(expiry)
    contract_type = find_contract_type_from_expiry(current_datetime, expiry)
  return expiry, contract_type
